import json
from datetime import datetime, timedelta

import requests
from django.core.cache import cache
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django_filters import FilterSet
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.views import APIView
from django.db.models import Count, Sum, Q, Avg

from utils.ali import AliPaySDK
from .models import Order, OrderStatusLog, OrderRating, OrderComplaint, OrderExtraFee
from .serializers import (
    OrderCreateSerializer, OrderUpdateSerializer,
    OrderCancelSerializer, OrderSerializer, OrderStatusLogSerializer,
    OrderRatingSerializer, OrderComplaintSerializer, OrderExtraFeeSerializer
)

# 高德地图key（建议放到settings中，这里直接写）
GAODE_KEY = '05a883255b18ffe0625dbddfcc1df112'


@method_decorator(csrf_exempt, name='dispatch')
class OrderCreateView(View):
    """
    简化的订单创建接口：
    1. 接收前端传来的起点、终点、乘客ID、路线信息等
    2. 直接创建订单（路线规划在前端完成）
    3. 返回订单信息
    """

    def post(self, request):
        data = json.loads(request.body)
        passenger_id = data.get('passenger_id')
        start_address = data.get('start_address')
        end_address = data.get('end_address')
        origin = data.get('origin')  # "经度,纬度"
        destination = data.get('destination')  # "经度,纬度"
        order_amount = data.get('order_amount')  # 前端计算的订单金额
        distance = data.get('distance')  # 前端获取的距离（米）
        duration = data.get('duration')  # 前端获取的时长（秒）
        # 验证必要参数
        if not all([passenger_id, start_address, end_address, origin, destination, order_amount]):
            return JsonResponse({'error': '缺少必要参数'}, status=400)

        # 解析坐标
        try:
            origin_lng, origin_lat = origin.split(',')
            destination_lng, destination_lat = destination.split(',')
        except ValueError:
            return JsonResponse({'error': '坐标格式错误'}, status=400)

        # 生成订单编号
        order_number = f'ODR{passenger_id}{Order.objects.count() + 1:06d}'

        # 创建订单（使用前端传来的路线信息）
        order = Order.objects.create(
            order_number=order_number,
            passenger_id=passenger_id,
            start_address=start_address,
            end_address=end_address,
            origin_lng=float(origin_lng),
            origin_lat=float(origin_lat),
            destination_lng=float(destination_lng),
            destination_lat=float(destination_lat),
            route_distance=distance or 0,
            route_duration=duration or 0,
            order_status=0,  # 0=待接单
            order_amount=float(order_amount)
        )

        # 返回订单信息
        return JsonResponse({
            'code': 200,
            'message': '订单创建成功',
            'data': {
                'order_id': order.id,
                'order_number': order.order_number,
                'distance': distance or 0,
                'duration': duration or 0,
                'order_amount': float(order_amount),
                'estimated_time': f"{(duration or 0) // 60}分{(duration or 0) % 60}秒" if duration else "未知",
                'distance_text': f"{(distance or 0) / 1000:.1f}公里" if distance else "未知",
                'route_info': {
                    'origin': {'lng': float(origin_lng), 'lat': float(origin_lat)},
                    'destination': {'lng': float(destination_lng), 'lat': float(destination_lat)},
                    'distance_km': round((distance or 0) / 1000, 1),
                    'duration_minutes': round((duration or 0) / 60, 1)
                }
            }
        })


@method_decorator(csrf_exempt, name='dispatch')
class RouteNavigationView(View):
    """
    路线导航API：
    1. 接收起点和终点坐标
    2. 调用高德地图API获取详细路线规划
    3. 返回导航步骤和路线信息
    """

    def post(self, request):
        data = json.loads(request.body)
        origin = data.get('origin')  # "经度,纬度"
        destination = data.get('destination')  # "经度,纬度"

        if not origin or not destination:
            return JsonResponse({'error': '起点和终点坐标不能为空'}, status=400)

        # 调用高德地图驾车路线规划API（获取详细步骤）
        url = f'https://restapi.amap.com/v3/direction/driving?origin={origin}&destination={destination}&key={GAODE_KEY}&extensions=all&steps_info=1'
        resp = requests.get(url)
        route_data = resp.json()

        if route_data.get('status') != '1':
            return JsonResponse({'error': '路线规划失败', 'detail': route_data}, status=400)

        # 解析路线信息
        path = route_data['route']['paths'][0]
        distance = int(path['distance'])  # 米
        duration = int(path['duration'])  # 秒
        polyline = path.get('polyline', '')  # 路线轨迹

        # 解析导航步骤
        navigation_steps = []
        for step in path.get('steps', []):
            navigation_steps.append({
                'instruction': step.get('instruction', ''),
                'distance': int(step.get('distance', 0)),
                'duration': int(step.get('duration', 0)),
                'polyline': step.get('polyline', ''),
                'action': step.get('action', ''),  # 转向动作
                'road_name': step.get('road', '')  # 道路名称
            })

        return JsonResponse({
            'code': 200,
            'message': '路线规划成功',
            'data': {
                'distance': distance,
                'duration': duration,
                'polyline': polyline,
                'distance_text': f"{distance / 1000:.1f}公里",
                'estimated_time': f"{duration // 60}分{duration % 60}秒",
                'navigation_steps': navigation_steps,
                'route_info': {
                    'origin': origin,
                    'destination': destination,
                    'distance_km': round(distance / 1000, 1),
                    'duration_minutes': round(duration / 60, 1)
                }
            }
        })


@method_decorator(csrf_exempt, name='dispatch')
class OrderPayView(View):
    """
    订单支付：
    1. 前端传订单ID
    2. 查询订单信息
    3. 调用支付宝SDK生成沙箱支付链接
    4. 返回支付链接给前端
    """

    def post(self, request, order_id):
        try:
            order = Order.objects.get(id=order_id)
        except Order.DoesNotExist:
            return JsonResponse({'error': '订单不存在'}, status=404)

        # 计算总金额（订单金额 + 额外费用）
        extra_fees = OrderExtraFee.objects.filter(order=order)
        total_extra_amount = sum(fee.amount for fee in extra_fees)
        total_amount = order.order_amount + total_extra_amount

        # 调用支付宝SDK生成支付链接
        alipay = AliPaySDK()
        pay_url = alipay.page_pay(
            out_trade_no=order.order_number,
            total_amount=total_amount,
            subject="滴滴出行订单支付"
        )
        # 返回支付链接和总金额信息
        return JsonResponse({
            'pay_url': pay_url,
            'order_amount': float(order.order_amount),
            'extra_fees_amount': float(total_extra_amount),
            'total_amount': float(total_amount)
        })


class AlipayNotifyView(APIView):
    def post(self, request):
        order_number = request.data.get("order_number")

        # 使用新的支付成功处理方法
        from finance.services import PaymentService
        import logging

        logger = logging.getLogger(__name__)
        logger.info(f"处理支付宝支付回调 - 订单号: {order_number}")

        if not order_number:
            logger.error("缺少订单号参数")
            return Response({'error': '缺少订单号'}, status=400)

        # 调用支付成功处理服务
        success, message = PaymentService.handle_payment_success(order_number)
        
        if success:
            logger.info(f"支付成功处理完成: {order_number}")
            return Response({'msg': 'success'})
        else:
            logger.error(f"支付成功处理失败: {order_number}, 错误: {message}")
            return Response({'error': message}, status=500)

class ManualPaymentSuccessView(APIView):
    """手动触发支付成功处理（用于沙箱环境测试）"""

    def post(self, request):
        import logging
        from finance.services import PaymentService

        logger = logging.getLogger(__name__)

        order_number = request.data.get("order_number")
        logger.info(f"手动支付确认请求 - 订单号: {order_number}")
        logger.info(f"请求数据: {request.data}")

        if not order_number:
            logger.error("缺少订单号参数")
            return Response({'error': '缺少订单号'}, status=400)

        # 使用新的支付成功处理方法
        success, message = PaymentService.handle_payment_success(order_number)
        
        if success:
            logger.info(f"手动支付成功处理完成: {order_number}")
            return Response({'msg': '支付成功处理完成'})
        else:
            logger.error(f"手动支付成功处理失败: {order_number}, 错误: {message}")
            return Response({'error': message}, status=500)



@method_decorator(csrf_exempt, name='dispatch')
class OrderAcceptView(View):
    """
    司机接单接口：
    1. 司机传入订单ID和司机ID
    2. 更新订单的driver_id和状态
    3. 返回订单信息（含司机ID）
    """

    def post(self, request):
        data = json.loads(request.body)
        order_id = data.get('order_id')
        driver_id = data.get('driver_id')
        try:
            order = Order.objects.get(id=order_id)
        except Order.DoesNotExist:
            return JsonResponse({'error': '订单不存在'}, status=404)
        if order.driver_id:
            return JsonResponse({'error': '订单已被接'}, status=400)
        order.driver_id = driver_id
        order.order_status = 0  # 保持待接单状态，司机需要点击"已上车"按钮
        order.save()
        return JsonResponse({
            'order_id': order.id,
            'order_number': order.order_number,
            'driver_id': order.driver_id,
            'order_status': order.order_status
        })


class OrderFilter(FilterSet):
    class Meta:
        model = Order
        fields = ['order_number']


class OrderViewSet(viewsets.ModelViewSet):
    """订单视图集"""
    queryset = Order.objects.all()
    serializer_class = OrderSerializer
    lookup_field = 'id'
    lookup_url_kwarg = 'id'
    filter_backends = [DjangoFilterBackend]
    filterset_class = OrderFilter

    def get_serializer_class(self):
        """根据不同的操作返回不同的序列化器"""
        if self.action == 'create':
            return OrderCreateSerializer
        elif self.action == 'update':
            return OrderUpdateSerializer
        return OrderSerializer

    def create(self, request, *args, **kwargs):
        """创建订单并推送给所有司机"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        try:
            order = serializer.save()

            # 推送给所有在线司机（使用Redis存储待接单列表）
            pending_orders_key = 'pending_orders'
            pending_orders = cache.get(pending_orders_key, [])
            pending_orders.append({
                'id': order.id,
                'order_number': order.order_number,
                'start_address': order.start_address,
                'end_address': order.end_address,
                'order_amount': str(order.order_amount),
                'create_time': order.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                'passenger_id': order.passenger_id
            })
            cache.set(pending_orders_key, pending_orders, timeout=3600)  # 1小时有效期

            return Response({
                'code': 200,
                'message': '订单创建成功，已推送给司机',
                'data': OrderSerializer(order).data
            })
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'订单创建失败: {str(e)}',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def cancel(self, request, id=None):
        """取消订单"""
        order = get_object_or_404(Order, id=id)

        # 检查订单状态是否允许取消
        if order.order_status not in [0, 1]:  # 只允许取消待接单和待出发状态的订单
            return Response({
                'code': 400,
                'message': '当前订单状态不允许取消',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        serializer = OrderCancelSerializer(data=request.data)
        if serializer.is_valid():
            try:
                order.order_status = 5  # 5=已取消
                order.save()

                # 记录取消日志
                OrderStatusLog.objects.create(
                    order=order,
                    status=5,  # 已取消
                    operator_type=1,  # 乘客操作
                    operator_id=request.data.get('passenger_id', 0),
                    create_time=datetime.now(),
                    remark=serializer.validated_data.get('cancel_reason', '用户主动取消订单')
                )

                # 如果是待接单状态，从Redis中移除
                if order.order_status == 0:
                    pending_orders = cache.get('pending_orders', [])
                    pending_orders = [o for o in pending_orders if o['id'] != order.id]
                    cache.set('pending_orders', pending_orders, timeout=3600)

                return Response({
                    'code': 200,
                    'message': '订单取消成功',
                    'data': OrderSerializer(order).data
                })
            except Exception as e:
                return Response({
                    'code': 500,
                    'message': f'订单取消失败: {str(e)}',
                    'data': None
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response({
            'code': 400,
            'message': '参数验证失败',
            'data': serializer.errors
        }, status=status.HTTP_400_BAD_REQUEST)

    @action(detail=True, methods=['get'])
    def status_logs(self, request, id=None):
        """获取订单状态日志"""
        order = get_object_or_404(Order, id=id)
        status_logs = OrderStatusLog.objects.filter(order=order).order_by('-create_time')
        serializer = OrderStatusLogSerializer(status_logs, many=True)

        return Response({
            'code': 200,
            'message': '获取订单状态日志成功',
            'data': serializer.data
        })


class DriverOrderView(APIView):
    """司机订单相关接口"""

    def get(self, request):
        """司机获取待接单列表"""
        # 获取所有待接单的订单（状态为0）
        orders = Order.objects.filter(order_status=0).order_by('-create_time')
        data = OrderSerializer(orders, many=True).data

        return Response({
            'code': 200,
            'message': '获取待接单列表成功',
            'data': data
        })

    def post(self, request):
        """司机接单"""
        order_id = request.data.get('order_id')
        driver_id = request.data.get('driver_id')

        # 判断是否缺少订单ID或司机ID参数
        if not order_id or not driver_id:
            return Response({
                'code': 400,
                'message': '缺少订单ID或司机ID参数',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 获取订单
            order = get_object_or_404(Order, id=order_id, order_status=0)

            # 更新订单信息
            order.driver_id = driver_id
            order.order_status = 1  # 待出发
            order.start_time = datetime.now()
            order.save()

            # 从待接单列表中移除
            pending_orders = cache.get('pending_orders', [])
            pending_orders = [o for o in pending_orders if o['id'] != order.id]
            cache.set('pending_orders', pending_orders, timeout=3600)

            # 记录接单日志
            OrderStatusLog.objects.create(
                order=order,
                status=1,  # 待出发
                operator_type=2,  # 司机操作
                operator_id=driver_id,
                create_time=datetime.now(),
                remark=f'司机{driver_id}接单成功'
            )

            return Response({
                'code': 200,
                'message': '接单成功',
                'data': OrderSerializer(order).data
            })

        except Order.DoesNotExist:
            return Response({
                'code': 404,
                'message': '订单不存在或已被其他司机接单',
                'data': None
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            return Response({
                'code': 500,
                'message': f'接单失败: {str(e)}',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class PassengerOrderView(APIView):
    """乘客订单相关接口"""

    def get(self, request):
        """获取乘客订单列表"""
        # 获取请求参数中的乘客ID
        passenger_id = request.query_params.get('passenger_id')
        # 如果没有传递乘客ID参数，返回错误信息
        if not passenger_id:
            return Response({
                'code': 400,
                'message': '缺少乘客ID参数',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        # 根据乘客ID查询订单，并按照创建时间降序排列
        orders = Order.objects.filter(passenger_id=passenger_id).order_by('-create_time')
        # 将查询结果序列化
        serializer = OrderSerializer(orders, many=True)

        # 返回成功信息
        return Response({
            'code': 200,
            'message': '获取乘客订单列表成功',
            'data': serializer.data
        })
    # 订单评价的增删改查API视图


class OrderRatingAPIView(APIView):
    """
        订单评价的增删改查视图
        """

    def get(self, request, pk=None):
        """
            查询订单评价
            如果提供pk则查询单条，否则查询所有
            """
        if pk:
            rating = get_object_or_404(OrderRating, pk=pk)
            serializer = OrderRatingSerializer(rating)
            return Response(serializer.data)
        ratings = OrderRating.objects.all()
        serializer = OrderRatingSerializer(ratings, many=True)
        return Response(serializer.data)

    def post(self, request):
        """
        新增订单评价
        """
        serializer = OrderRatingSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        """
        删除订单评价
        """
        rating = get_object_or_404(OrderRating, pk=pk)
        rating.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class OrderComplaintAPIView(APIView):
    """
    订单投诉的增删查视图（乘客对司机投诉）
    只允许状态为0-待处理和1-已处理
    """

    def get(self, request, pk=None):
        """
        查询订单投诉
        - 如果提供pk则查询单条投诉，否则查询所有投诉
        - 支持按订单ID过滤（order_id参数）
        - 只返回状态为0或1的投诉
        """
        if pk:
            complaint = get_object_or_404(OrderComplaint, pk=pk)
            # 只允许返回状态为0或1的投诉
            if complaint.status not in [0, 1]:
                return Response({'detail': '投诉状态无效'}, status=status.HTTP_400_BAD_REQUEST)
            serializer = OrderComplaintSerializer(complaint)
            return Response(serializer.data)
        
        # 获取查询参数
        order_id = request.query_params.get('order_id')
        
        # 构建查询条件
        queryset = OrderComplaint.objects.filter(status__in=[0, 1])
        
        # 如果提供了订单ID，则按订单过滤
        if order_id:
            queryset = queryset.filter(order_id=order_id)
        
        serializer = OrderComplaintSerializer(queryset, many=True)
        return Response(serializer.data)

    def post(self, request):
        """
        新增订单投诉
        - 乘客提交对司机的投诉
        - 只允许提交状态为0或1的投诉，默认为0
        """
        data = request.data.copy()
        # 如果未传status，默认为0
        status_value = int(data.get('status', 0))
        if status_value not in [0, 1]:
            return Response({'status': '只允许0-待处理或1-已处理'}, status=status.HTTP_400_BAD_REQUEST)
        data['status'] = status_value
        serializer = OrderComplaintSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        """
        删除订单投诉
        - 根据投诉ID删除指定投诉记录
        """
        complaint = get_object_or_404(OrderComplaint, pk=pk)
        complaint.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

    def patch(self, request, pk):
        """
        修改投诉状态和处理结果
        - 只能修改status和result字段
        - 修改status时必须同时提供result
        - status只允许0-待处理或1-已处理
        """
        complaint = get_object_or_404(OrderComplaint, pk=pk)
        data = request.data
        # 只允许修改status和result
        status_value = data.get('status')
        result_value = data.get('result')
        update_fields = {}
        # 如果要修改status
        if status_value is not None:
            try:
                status_value = int(status_value)
            except Exception:
                return Response({'status': '状态必须为数字0或1'}, status=status.HTTP_400_BAD_REQUEST)
            if status_value not in [0, 1]:
                return Response({'status': '只允许0-待处理或1-已处理'}, status=status.HTTP_400_BAD_REQUEST)
            # 修改状态时必须有处理结果
            if not result_value:
                return Response({'result': '修改状态时必须同时提供处理结果'}, status=status.HTTP_400_BAD_REQUEST)
            update_fields['status'] = status_value
            update_fields['result'] = result_value
        # 只修改处理结果
        elif result_value is not None:
            update_fields['result'] = result_value
        else:
            return Response({'detail': '必须提供status或result字段'}, status=status.HTTP_400_BAD_REQUEST)
        # 执行更新
        for k, v in update_fields.items():
            setattr(complaint, k, v)
        complaint.save()
        serializer = OrderComplaintSerializer(complaint)
        return Response(serializer.data)


class OrderExtraFeeAPIView(APIView):
    """
    订单额外费用的增、改、查视图
    - 费用类型为'附加费'时，描述为必填
    """

    def get(self, request, pk=None):
        """
        查询订单额外费用
        - 如果提供pk则查询单条，否则查询所有
        - 支持按订单ID过滤（order_id参数）
        """
        if pk:
            extra_fee = get_object_or_404(OrderExtraFee, pk=pk)
            serializer = OrderExtraFeeSerializer(extra_fee)
            return Response(serializer.data)
        
        # 获取查询参数
        order_id = request.query_params.get('order_id')
        
        # 构建查询条件
        queryset = OrderExtraFee.objects.all()
        
        # 如果提供了订单ID，则按订单过滤
        if order_id:
            queryset = queryset.filter(order_id=order_id)
        
        serializer = OrderExtraFeeSerializer(queryset, many=True)
        return Response(serializer.data)

    def post(self, request):
        """
        新增订单额外费用
        - 费用类型为'附加费'时，描述为必填
        """
        serializer = OrderExtraFeeSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def put(self, request, pk):
        """
        修改订单额外费用
        - 费用类型为'附加费'时，描述为必填
        """
        extra_fee = get_object_or_404(OrderExtraFee, pk=pk)
        serializer = OrderExtraFeeSerializer(extra_fee, data=request.data, partial=False)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class DriverDailyStatsView(APIView):
    """司机今日统计数据接口"""

    def get(self, request):
        """获取司机今日统计数据"""
        driver_id = request.GET.get('driver_id')

        if not driver_id:
            return Response({
                'code': 400,
                'message': '缺少driver_id参数',
                'data': None
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 获取今日日期范围
            today = datetime.now().date()
            today_start = datetime.combine(today, datetime.min.time())
            today_end = datetime.combine(today, datetime.max.time())

            # 查询今日司机的所有订单
            today_orders = Order.objects.filter(
                driver_id=driver_id,
                create_time__range=[today_start, today_end]
            )

            # 统计今日接单数量（所有状态的订单）
            total_orders_today = today_orders.count()

            # 统计今日完成订单数量（已支付状态：order_status=4或5）
            completed_orders_today = today_orders.filter(
                Q(order_status=4) | Q(order_status=5)
            ).count()

            # 计算今日收入（已支付订单的金额总和）
            daily_income = today_orders.filter(
                Q(order_status=4) | Q(order_status=5)
            ).aggregate(
                total_income=Sum('order_amount')
            )['total_income'] or 0

            # 计算平均评分（从订单评价表中获取）
            avg_rating = OrderRating.objects.filter(
                driver_id=driver_id
            ).aggregate(
                avg_rating=Avg('rating')
            )['avg_rating'] or 0

            return Response({
                'code': 200,
                'message': '获取统计数据成功',
                'data': {
                    'total_orders_today': total_orders_today,
                    'completed_orders_today': completed_orders_today,
                    'daily_income': float(daily_income),
                    'avg_rating': round(float(avg_rating), 1) if avg_rating else 0,
                    'date': today.strftime('%Y-%m-%d')
                }
            })

        except Exception as e:
            return Response({
                'code': 500,
                'message': f'获取统计数据失败: {str(e)}',
                'data': None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
